package com.sanhuo.file.service;

import com.sanhuo.file.FileVO;
import com.sanhuo.file.dao.FilesMapper;
import com.sanhuo.lib.ExceptionUtil;
import com.sanhuo.lib.exception.GlobalException;
import com.sanhuo.triild.Basic.BaseMapper;
import com.sanhuo.triild.Basic.BaseService;
import com.sanhuo.triild.annotation.MapperWire;
import com.sanhuo.utils.basic.BeanUtil;
import com.sanhuo.utils.basic.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.sanhuo.file.entity.Files;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

@Service
@Transactional
public class FileService extends BaseService<Files> {

    private final String baseIp = "localhost";
    private final String url = "/file/download?id=";
    private final String localFolder = "c:/mcts/";//根目录
    private static final Random random = new Random();//随机数生成目录
    private final String month = "yyyyMM";//用月份来做目录
    private final SimpleDateFormat sdf = new SimpleDateFormat(month); //将date转字符串

    @MapperWire
    private FilesMapper filesMapper;


    private String getFolder() {
        return localFolder + sdf.format(new Date()) + "/" + random.nextInt(9) + random.nextInt(9) + "/";
    }

    private String getLocalFileName(String fileName) {
        String type = fileName.substring(fileName.lastIndexOf("."));
        return StringUtil.UUID().substring(15) + type;
    }

    public Files upload(MultipartFile file) {
        String url = getFolder() + getLocalFileName(file.getOriginalFilename());
        File localFile = new File(url);
        if (!localFile.getParentFile().exists()) {
            localFile.getParentFile().mkdirs();
        }
        Files result = null;
        try {
            file.transferTo(localFile);
            result = new Files();
            result.setId(StringUtil.UUID());
            result.setCreateTime(new Date());
            result.setLocalSite(url);
            result.setName(file.getOriginalFilename());
            result.setType(file.getContentType());
            save(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }


    public void downloadByFilesId(String fileId, HttpServletRequest request,
                                  HttpServletResponse response) throws IOException {
        Files files = findById(fileId);
        ExceptionUtil.throwException(BeanUtil.isNull(files), "下载文件不存在!");
        // 初始化下载的文件
        File file = new File(files.getLocalSite());
        download(file, files.getName(), request, response);

    }

    public void downloadLocalFile(String filepath, String fileName, HttpServletRequest request,
                                  HttpServletResponse response) throws IOException {
        // 初始化下载的文件
        File file = new File(filepath);
        download(file, fileName, request, response);
        // 设置响应头 Response Header 输出。

    }

    public void download(File file, String fileName, HttpServletRequest request,
                         HttpServletResponse response) {
        response.reset(); // 清空response
//        String contentType = request.getServletContext().getMimeType(files.getLocalSite());
////        if (contentType == null) {
//            contentType = "application/octet-stream";
////        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");

        response.addHeader("Content-Length", "" + file.length());
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "No-cache");
        response.setDateHeader("Expires", 0);

        try (FileInputStream fis = new FileInputStream(file);
             BufferedInputStream bis = new BufferedInputStream(fis);
             OutputStream toClient = new BufferedOutputStream(response.getOutputStream())) {
            byte[] buffer = new byte[1024];// 定义buffer大小,相当每次从文件读取1024byte就往输出流写。

            // byte[] buffer = new byte[fis.available()]; //一次过将文件读进内存
            // 相当每次从文件读取1024byte就往输出流写。
            int len = -1;
            while ((len = bis.read(buffer)) != -1) {
                toClient.write(buffer, 0, len);
                toClient.flush();
            }

        } catch (IOException e) {
            throw new GlobalException(e.getMessage());
        }
    }

    public void setDownUrl(FileVO vo) {
        String downUrl = baseIp + url + vo.getId();
        vo.setDownUrl(downUrl);
    }

    public FileVO detail(String id) throws IllegalAccessException {
        Files files = findById(id);
        FileVO vo = new FileVO();
        BeanUtil.copyBean(files, vo);
        setDownUrl(vo);
        return vo;
    }

    public List<FileVO> findAll(List<String> ids) throws IllegalAccessException {
        List<Files> files = filesMapper.findAllByIds(ids);
        List<FileVO> result = new LinkedList<>();
        for (Files file : files) {
            FileVO vo = new FileVO();
            BeanUtil.copyBean(file, vo);
            setDownUrl(vo);
            result.add(vo);
        }
        return result;
    }


    @Override
    public BaseMapper getBaseMapper() {
        return filesMapper;
    }
}
